#pragma  once
#include <boost/shared_ptr.hpp>

template<typename T, typename dataT, typename cmpT = less<dataT> >
class RefObject {
public:
	RefObject() {
		self.reset(new dataT);
	}
	virtual ~RefObject(){}
public:
	template<typename cmpT2>
	void swap(RefObject<T, dataT, cmpT2>& other) {
		self.swap(other.self);
	}

	T Copy()const {
		T other;
		*(other.self) = *(self);
		return other;
	}
	int Compare(const RefObject<T, dataT, cmpT>& other)const {
		const dataT& left = *(self.get());
		const dataT& right = *(other.self.get());
		if(cmp(left, right)){
			return -1;
		}
		if(cmp(right, left)){
			return 1;
		}
		return 0;
	}
protected:
	long RefCount() const {
		return self.use_count();
	}
	
protected:
	static cmpT cmp;
	boost::shared_ptr<dataT> self;
};
template<typename T, typename dataT, typename cmpT >
cmpT RefObject<T, dataT, cmpT>::cmp;

template<typename T, typename dataT, typename cmpT>  inline
void swap(RefObject<T, dataT, cmpT>& left, RefObject<T, dataT, cmpT>& right) {
	left.swap(right);
}

template<typename T, typename dataT, typename cmpT>  inline
bool operator <(const RefObject<T, dataT, cmpT>& left, const RefObject<T, dataT, cmpT>& right){
	return left.Compare(right) <0;
}
template<typename T, typename dataT, typename cmpT>  inline
bool operator >(const RefObject<T, dataT, cmpT>& left, const RefObject<T, dataT, cmpT>& right){
	return left.Compare(right) >0;
}
template<typename T, typename dataT, typename cmpT>  inline
bool operator ==(const RefObject<T, dataT, cmpT>& left, const RefObject<T, dataT, cmpT>& right){
	return left.Compare(right) == 0;
}


template<typename T, typename dataT, typename cmpT>  inline
bool operator >=(const RefObject<T, dataT, cmpT>& left, const RefObject<T, dataT, cmpT>& right){
	return left.Compare(right) >=0;
}
template<typename T, typename dataT, typename cmpT>  inline
bool operator <=(const RefObject<T, dataT, cmpT>& left, const RefObject<T, dataT, cmpT>& right){
	return left.Compare(right) <= 0;
}
